﻿using System;
using System.Collections.Generic;
//using System.Linq;
using System.Text;
using System.Data;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Threading;
using DaInterFace;
using DaInterFace.Mobile;
using DaInterFace.PDA;
using DaInterFace.SYN;
using DaInterFace.XMode;
using DaInterFace.UMode;

using DaFunction.Mobile;
using DaFunction.PDA;
using DaFunction.SYN;
using DaFunction.XMode;
using DaFunction.Transfer;

using System.Reflection;
using System.IO;
namespace DaFunction
{
    public class DataCenter : IDataCenter
    {
        private const int MAX_LINE = 1000;
        private DataCenter daCenter;
        private IConfig daConfig;
        private IDataBase daData;
        private IMobile daMobile;
        private IPDA daPDA;
        private ISYN daSYN;
        private IXMode daXMode;
        private IUMode daUMode;
        private int socketPort;
        private String _right = "";
        private Lisense _lisense;

        public IConfig DaConfig { get { return daConfig; } }
        public IDataBase DaData { get { return daData; } }
        public IMobile DaMobile { get { return daMobile; } }
        public IPDA DaPDA { get { return daPDA; } }
        public ISYN DaSYN { get { return daSYN; } }
        public IXMode DaXMode { get { return daXMode; } }
        public int SocketPort { get { return socketPort; } }

        public IUMode DaUMode { get { return daUMode; } }


        public DataCenter()
        {
            daConfig = new Config();

            daData = new DataBase(daConfig.Get("Page00_Conn"));
            daMobile = new DaFunction.Mobile.Mobile(daData, daConfig);
            daPDA = new DaFunction.PDA.PDA(daData, daConfig);
            daSYN = new DaFunction.SYN.SYN(daData, daConfig);
            daXMode = new DaFunction.XMode.XMode(daData, daConfig);
            
            if (Common.CBool(daConfig.Get("Page05_Enable").ToString()))
            {
                daUMode = new DaSub.UMode.UMode(this);
            }
        }

        public void Init()
        {
            TransferLoad();
            if (CheckAuthorization())
            {
                DaData.Message(MessageType.Note, String.Format("授权文件验证成功，到期日：{0}。", _lisense.ExpiryDate.ToString("yyyy年MM月dd日")));

                Thread threadMobile = new Thread(MobileLoad);
                threadMobile.IsBackground = true;
                threadMobile.Name = "手机端服务";
                threadMobile.Start();

                Thread threadPDA = new Thread(PDALoad);
                threadPDA.IsBackground = true;
                threadPDA.Name = "手持设备服务";
                threadPDA.Start();

                Thread threadSYN = new Thread(SYNLoad);
                threadSYN.IsBackground = true;
                threadSYN.Name = "数据同步接口服务";
                threadSYN.Start();

                Thread threadXMode = new Thread(XModeLoad);
                threadXMode.IsBackground = true;
                threadXMode.Name = "模块接口服务";
                threadXMode.Start();

                Thread dataTimer = new Thread(DataTimer);
                dataTimer.IsBackground = true;
                dataTimer.Name = "定时数据执行器";
                dataTimer.Start();

                Thread threadFrp = new Thread(FrpTimer);
                threadFrp.IsBackground = true;
                threadFrp.Name = "反向代理";
                threadFrp.Start();

                //daData.Test();
            }
        }

        //重新配置并启动代理
        public void ProxyReset()
        {
            try
            {
                StringBuilder frpcfg = new StringBuilder();
                frpcfg.AppendFormat("[common]\r\n");
                frpcfg.AppendFormat("server_addr = frp.zzlysbd.com\r\n");
                frpcfg.AppendFormat("server_port = 7000\r\n");
                frpcfg.AppendFormat("privilege_token=jkxsip\r\n");
                frpcfg.AppendFormat("[tcp{0}]\r\n", SocketPort);
                frpcfg.AppendFormat("type = tcp\r\n");
                frpcfg.AppendFormat("local_ip = 127.0.0.1\r\n");
                frpcfg.AppendFormat("local_port = {0}\r\n", SocketPort);
                frpcfg.AppendFormat("remote_port = {0}\r\n", SocketPort);

                frpcfg.AppendFormat("[vnc{0}]\r\n", SocketPort - 10000);
                frpcfg.AppendFormat("type = tcp\r\n");
                frpcfg.AppendFormat("local_ip = 127.0.0.1\r\n");
                frpcfg.AppendFormat("local_port = {0}\r\n", 4899);
                frpcfg.AppendFormat("remote_port = {0}\r\n", SocketPort - 10000);

                frpcfg.AppendFormat("[web{0}]\r\n", SocketPort);
                frpcfg.AppendFormat("type=http\r\n");
                frpcfg.AppendFormat("local_port=18701\r\n");
                frpcfg.AppendFormat("privilege_mode = true\r\n");
                frpcfg.AppendFormat("custom_domains={0}.zzlysbd.com\r\n", SocketPort);

                String path = "FRP\\frpc.ini";
                File.Delete(path);
                FileStream frn = File.Create(path);
                frn.Close();
                FileInfo fi = new FileInfo(path);

                using (FileStream fs = fi.OpenWrite())
                {
                    StreamWriter w = new StreamWriter(fs);
                    w.BaseStream.Seek(0, SeekOrigin.End);
                    w.Write(frpcfg.ToString());
                    w.Flush();
                    w.Close();
                }

                KillProcess("frpc");
                //KillProcess("frpproxy");

                System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(GetSystemRoot() + "FRP\\run.bat"));
                //System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(GetSystemRoot() + "Proxy\\proxy.bat"));
            }
            catch (Exception ex)
            {
                DaData.Message(MessageType.Error, ex.Message);
            }
        }

        private void KillProcess(string processName)
        {
            try
            {
                System.Diagnostics.Process[] thisproc = System.Diagnostics.Process.GetProcessesByName(processName);
                //thisproc.lendth:名字为进程总数

                if (thisproc.Length > 0)
                {
                    for (int i = 0; i < thisproc.Length; i++)
                    {
                        if (!thisproc[i].CloseMainWindow()) //尝试关闭进程 释放资源
                        {
                            thisproc[i].Kill(); //强制关闭
                            thisproc[i].WaitForExit();
                        }
                        Console.WriteLine("进程 {0}关闭成功", processName);
                    }
                }
                else
                {
                    Console.WriteLine("进程 {0} 关闭失败!", processName);
                }
            }
            catch //出现异常，表明 kill 进程失败
            {
                Console.WriteLine("结束进程{0}出错！", processName);
            }
        }

        private void FrpTimer()
        {
            DateTime _dataProxyTime = DateTime.Now;

            int _dataProxyRuning = 0;

            while (true)
            {
                try
                {
                    if (!ProcessRuning("frpc"))
                    {
                        switch (_dataProxyRuning)
                        {
                            case 0:
                                System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(GetSystemRoot() + "FRP\\run.bat");
                                System.Diagnostics.Process.Start(startInfo);
                                _dataProxyTime = DateTime.Now;
                                _dataProxyRuning = 1;
                                break;
                            case 1: //等待启动中
                                if (DateTime.Now - _dataProxyTime > TimeSpan.FromSeconds(12))
                                    _dataProxyRuning = 0;
                                break;

                        }
                    }
                    else
                    {
                        if (_dataProxyRuning == 1)
                        {
                            _dataProxyRuning = 0;
                            DaData.Message(MessageType.Note, String.Format("代理服务已启动，端口号：{0}，数据地址:{0}.zzlysbd.com,远程端口:{1}", socketPort, socketPort - 10000));
                        }
                    }
                }
                catch { }

                Thread.Sleep(3000);
            }
        }

        private Boolean ProcessRuning(String proName)
        {
            System.Diagnostics.Process[] proc = System.Diagnostics.Process.GetProcessesByName(proName);
            return proc.Length != 0;
        }

        private void DataTimer()
        {
            //Dictionary<string, SetOfBook> books = DaData.GetAccounts();
            //while (true)
            //{
            //    foreach (SetOfBook book in books.Values)
            //    {
            //        Recordset ds = DaData.ExeProcedure(book.FNumber, "EXEC KEW_TIMER");
            //        if (!ds.Enable)
            //        {
            //            DaData.Message(MessageType.Error, String.Format("账套{0}执行定时数据时出现错误:{1}", book.FNumber, ds.Message));
            //        }
            //    }

            //    Thread.Sleep(60000); //每分钟执行一次
            //}
        }

        public String GetSystemRoot()
        {
            return System.Environment.CurrentDirectory + "\\";
        }

        private void MobileLoad()
        {
            MobileApi.DaMobile = daMobile;
            Uri baseAddress = new Uri(String.Format("http://localhost:18701/MobileService.svc/", daConfig.Get("Page01_Port")));
            ServiceHost host = new ServiceHost(typeof(MobileApi), baseAddress);

            host.AddServiceEndpoint(typeof(IMobileApi), new BasicHttpBinding(), "");
            ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
            behavior.HttpGetEnabled = true;
            behavior.HttpGetUrl = new Uri(String.Format("http://localhost:18701/MobileService.svc/", daConfig.Get("Page01_Port")));
            host.Description.Behaviors.Add(behavior);

            try
            {
                host.Open();
                daMobile.Message(MessageType.Note, "手机服务端加载成功,访问地址：" + baseAddress.AbsoluteUri);
            }
            catch (Exception ex)
            {
                daMobile.Message(MessageType.Error, "手机服务端加载失败:" + ex.Message);
            }
        }

        private void PDALoad()
        {
            PDAApi.DaPDA = daPDA;
            Uri baseAddress = new Uri(String.Format("http://localhost:18701/PDAService.svc/", daConfig.Get("Page02_Port")));
            ServiceHost host = new ServiceHost(typeof(PDAApi), baseAddress);

            host.AddServiceEndpoint(typeof(IPDAApi), new BasicHttpBinding(), "");
            ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
            behavior.HttpGetEnabled = true;
            behavior.HttpGetUrl = new Uri(String.Format("http://localhost:18701/PDAService.svc/", daConfig.Get("Page02_Port")));
            host.Description.Behaviors.Add(behavior);

            try
            {
                host.Open();
                daPDA.Message(MessageType.Note, "手持设备服务加载成功,访问地址：" + baseAddress.AbsoluteUri);
            }
            catch (Exception ex)
            {
                daPDA.Message(MessageType.Error, "手持设备服务加载失败:" + ex.Message);
            }
        }

        private void SYNLoad()
        {

            SYNApi.DaSYN = daSYN;
            Uri baseAddress = new Uri(String.Format("http://localhost:{0}/SYNService.svc/", daConfig.Get("Page03_Port")));
            ServiceHost host = new ServiceHost(typeof(SYNApi), baseAddress);

            host.AddServiceEndpoint(typeof(ISYNApi), new BasicHttpBinding(), "");
            ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
            behavior.HttpGetEnabled = true;
            behavior.HttpGetUrl = new Uri(String.Format("http://localhost:{0}/SYNService.svc/", daConfig.Get("Page03_Port")));
            host.Description.Behaviors.Add(behavior);

            try
            {
                host.Open();
                daSYN.Message(MessageType.Note, "数据同步接口加载成功,访问地址：" + baseAddress.AbsoluteUri, 0);
            }
            catch (Exception ex)
            {
                daSYN.Message(MessageType.Error, "数据同步接口加载失败:" + ex.Message, 0);
            }
        }

        private void XModeLoad()
        {
            XModeAPI.DaXMode = daXMode;
            Uri baseAddress = new Uri(String.Format("http://localhost:{0}/XMode.svc/", daConfig.Get("Page04_Port")));
            ServiceHost host = new ServiceHost(typeof(XModeAPI), baseAddress);

            host.AddServiceEndpoint(typeof(IXModeApi), new BasicHttpBinding(), "");
            ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
            behavior.HttpGetEnabled = true;
            behavior.HttpGetUrl = new Uri(String.Format("http://localhost:{0}/XMode.svc/", daConfig.Get("Page04_Port")));
            host.Description.Behaviors.Add(behavior);

            try
            {
                host.Open();
                daXMode.Message(MessageType.Note, "模块接口加载成功,访问地址：" + baseAddress.AbsoluteUri, 0);
            }
            catch (Exception ex)
            {
                daXMode.Message(MessageType.Error, "模块接口加载失败:" + ex.Message, 0);
            }
        }

        private void TransferLoad()
        {
            //PDAApi.DaPDA = daPDA;
            Uri baseAddress = new Uri(String.Format("http://localhost:{0}/TransferService.svc", 18730));
            ServiceHost host = new ServiceHost(typeof(TransferApi), baseAddress);

            host.AddServiceEndpoint(typeof(ITransferApi), new BasicHttpBinding(), "");
            ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
            behavior.HttpGetEnabled = true;
            behavior.HttpGetUrl = new Uri(String.Format("http://localhost:{0}/TransferService.svc", 18730));
            host.Description.Behaviors.Add(behavior);

            try
            {
                host.Open();
                daData.Message(MessageType.Note, "数据中转已开启：" + baseAddress.AbsoluteUri);
            }
            catch (Exception ex)
            {
                daData.Message(MessageType.Error, "数据中转启动失败:" + ex.Message);
            }
        }

        #region 授权相关

        private Boolean CheckAuthorization()
        {
            UpDateLisenseFromWeb();
            CustomRight right = GetLisense();
            Boolean flag = false;
            if (right == null)
            {
                daData.Message(MessageType.Error, "未获得授权文件");
            }
            else if (right.Fingerprint != GetFingerprint())
            {
                
            }
            else
            {
                _lisense = new Lisense(right);
                if (right.ExpiryDate < GetSystemTime())
                {
                    daData.Message(MessageType.Error, String.Format("授权文件到期日为{0},已过期", right.ExpiryDate.ToString("yyyy-MM-dd")));
                }
                else
                {
                    socketPort = right.Port;
                    flag = true;
                }
            }
            return flag;
        }

        /// <summary>
        /// 序列化
        /// </summary>
        public String SerializeByJson(object instance)
        {
            string str = Newtonsoft.Json.JsonConvert.SerializeObject(instance);
            return str;
        }
        /// <summary>
        /// 反序列化
        /// </summary>
        public Object DeserializeByJson(string str, Type type)
        {
            Object instance = Newtonsoft.Json.JsonConvert.DeserializeObject(str, type);
            return instance;
        }

        /// <summary>
        /// 获得设备指纹
        /// </summary>
        /// <returns></returns>
        public String GetFingerprint()
        {
            String finger = "";
            try
            {
                finger = FingerPrint.Value();
            }
            catch (Exception ex)
            {
                daData.Message(MessageType.Error, ex.Message);
            }
            return finger;
        }
        /// <summary>
        /// 获得授权信息
        /// </summary>
        /// <returns></returns>
        public CustomRight GetLisense()
        {
            CustomRight right = null;
            try
            {
                String encrypt = daConfig.Get("Right_EncryptInfo");
                String decrypt = Rights.DecryptString(encrypt);
                right = (CustomRight)this.DeserializeByJson(decrypt, typeof(CustomRight));


            }
            catch (Exception ex)
            {
                daData.Message(MessageType.Error, "解析授权时出错：" + ex.StackTrace);
            }
            return right;
        }

        public DateTime GetSystemTime()
        {
            return DateTime.Now;
        }

        public String CheckLisense(String encrypt)
        {
            CustomRight right = null;
            try
            {
                String decrypt = Rights.DecryptString(encrypt);
                right = (CustomRight)this.DeserializeByJson(decrypt, typeof(CustomRight));
                if (right == null)
                {
                    return "未获得授权文件";
                }
                else if (right.Fingerprint != GetFingerprint())
                {
                    return "无效的授权文件";
                }
                else if (right.ExpiryDate < GetSystemTime())
                {
                    return String.Format("授权文件{0}已过期", right.ExpiryDate);
                }
                else
                {
                    socketPort = right.Port;
                    return "";
                }
            }
            catch (Exception ex)
            {
                return "解析授权时出错：" + ex.Message;
            }
        }

        public Boolean UpDateLisenseFromWeb()
        {
            SipService.SipService server = new SipService.SipService();
            String right = null;
            try
            {
                right = server.GetWebRight(GetFingerprint());
                if (right != "" && right != _right)
                {
                    _right = right;
                    daConfig.Set("Right_EncryptInfo", right);
                }
                else
                {
                    daData.Message(MessageType.Error, "请先到Clue系统获得授权");
                }
                return true;
            }
            catch (Exception ex)
            {
                daData.Message(MessageType.Error, ex.Message);
                return false;
            }
        }
        #endregion
    }
}
